package org.apache.geronimo.daytrader.javaee6.web;

import javax.servlet.*;
import javax.servlet.http.*;

import org.apache.geronimo.daytrader.javaee6.utils.*;
import java.util.*;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import org.apache.geronimo.daytrader.javaee6.core.api.TradeServices;
import org.apache.geronimo.daytrader.javaee6.entities.HoldingDataBean;
import org.apache.geronimo.daytrader.javaee6.entities.QuoteDataBean;

/**
 *Abhishek: Changing the TradeScenarioServelt
 * It will do a multiplication from 1 to 1000
 * Then send a request for a quote
 */
@WebServlet(value = "/scenario", initParams = {
        @WebInitParam(name = "runTimeMode", value = "Web JPA"),
        @WebInitParam(name = "orderProcessingMode", value = "Synchronous"),
        @WebInitParam(name = "accessMode", value = "Standard"),
        @WebInitParam(name = "webServicesEndpoint", value = "http://localhost:8080/daytrader/services/TradeWSServices"),
        @WebInitParam(name = "workloadMix", value = "Standard"),
        @WebInitParam(name = "WebInterface", value = "JSP"),
        @WebInitParam(name = "maxUsers", value = "200"),
        @WebInitParam(name = "maxQuotes", value = "400"),
        @WebInitParam(name = "primIterations", value = "1"),
        @WebInitParam(name = "cachingType", value = "No Caching")})
public class TradeScenarioServlet extends HttpServlet {
	public static String[] symbolArray = {"s:0",
		"s:1",
		"s:10",
		"s:100",
		"s:101",
		"s:102",
		"s:103",
		"s:104",
		"s:105",
		"s:106",
		"s:107",
		"s:108",
		"s:109",
		"s:11",
		"s:110",
		"s:111",
		"s:112",
		"s:113",
		"s:114",
		"s:115",
		"s:116",
		"s:117",
		"s:118",
		"s:119",
		"s:12",
		"s:120",
		"s:121",
		"s:122",
		"s:123",
		"s:124",
		"s:125",
		"s:126",
		"s:127",
		"s:128",
		"s:129",
		"s:13",
		"s:130",
		"s:131",
		"s:132",
		"s:133",
		"s:134",
		"s:135",
		"s:136",
		"s:137",
		"s:138",
		"s:139",
		"s:14",
		"s:140",
		"s:141",
		"s:142",
		"s:143",
		"s:144",
		"s:145",
		"s:146",
		"s:147",
		"s:148",
		"s:149",
		"s:15",
		"s:150",
		"s:151",
		"s:152",
		"s:153",
		"s:154",
		"s:155",
		"s:156",
		"s:157",
		"s:158",
		"s:159",
		"s:16",
		"s:160",
		"s:161",
		"s:162",
		"s:163",
		"s:164",
		"s:165",
		"s:166",
		"s:167",
		"s:168",
		"s:169",
		"s:17",
		"s:170",
		"s:171",
		"s:172",
		"s:173",
		"s:174",
		"s:175",
		"s:176",
		"s:177",
		"s:178",
		"s:179",
		"s:18",
		"s:180",
		"s:181",
		"s:182",
		"s:183",
		"s:184",
		"s:185",
		"s:186",
		"s:187",
		"s:188",
		"s:189",
		"s:19",
		"s:190",
		"s:191",
		"s:192",
		"s:193",
		"s:194",
		"s:195",
		"s:196",
		"s:197",
		"s:198",
		"s:199",
		"s:2",
		"s:20",
		"s:200",
		"s:201",
		"s:202",
		"s:203",
		"s:204",
		"s:205",
		"s:206",
		"s:207",
		"s:208",
		"s:209",
		"s:21",
		"s:210",
		"s:211",
		"s:212",
		"s:213",
		"s:214",
		"s:215",
		"s:216",
		"s:217",
		"s:218",
		"s:219",
		"s:22",
		"s:220",
		"s:221",
		"s:222",
		"s:223",
		"s:224",
		"s:225",
		"s:226",
		"s:227",
		"s:228",
		"s:229",
		"s:23",
		"s:230",
		"s:231",
		"s:232",
		"s:233",
		"s:234",
		"s:235",
		"s:236",
		"s:237",
		"s:238",
		"s:239",
		"s:24",
		"s:240",
		"s:241",
		"s:242",
		"s:243",
		"s:244",
		"s:245",
		"s:246",
		"s:247",
		"s:248",
		"s:249",
		"s:25",
		"s:250",
		"s:251",
		"s:252",
		"s:253",
		"s:254",
		"s:255",
		"s:256",
		"s:257",
		"s:258",
		"s:259",
		"s:26",
		"s:260",
		"s:261",
		"s:262",
		"s:263",
		"s:264",
		"s:265",
		"s:266",
		"s:267",
		"s:268",
		"s:269",
		"s:27",
		"s:270",
		"s:271",
		"s:272",
		"s:273",
		"s:274",
		"s:275",
		"s:276",
		"s:277",
		"s:278",
		"s:279",
		"s:28",
		"s:280",
		"s:281",
		"s:282",
		"s:283",
		"s:284",
		"s:285",
		"s:286",
		"s:287",
		"s:288",
		"s:289",
		"s:29",
		"s:290",
		"s:291",
		"s:292",
		"s:293",
		"s:294",
		"s:295",
		"s:296",
		"s:297",
		"s:298",
		"s:299",
		"s:3",
		"s:30",
		"s:300",
		"s:301",
		"s:302",
		"s:303",
		"s:304",
		"s:305",
		"s:306",
		"s:307",
		"s:308",
		"s:309",
		"s:31",
		"s:310",
		"s:311",
		"s:312",
		"s:313",
		"s:314",
		"s:315",
		"s:316",
		"s:317",
		"s:318",
		"s:319",
		"s:32",
		"s:320",
		"s:321",
		"s:322",
		"s:323",
		"s:324",
		"s:325",
		"s:326",
		"s:327",
		"s:328",
		"s:329",
		"s:33",
		"s:330",
		"s:331",
		"s:332",
		"s:333",
		"s:334",
		"s:335",
		"s:336",
		"s:337",
		"s:338",
		"s:339",
		"s:34",
		"s:340",
		"s:341",
		"s:342",
		"s:343",
		"s:344",
		"s:345",
		"s:346",
		"s:347",
		"s:348",
		"s:349",
		"s:35",
		"s:350",
		"s:351",
		"s:352",
		"s:353",
		"s:354",
		"s:355",
		"s:356",
		"s:357",
		"s:358",
		"s:359",
		"s:36",
		"s:360",
		"s:361",
		"s:362",
		"s:363",
		"s:364",
		"s:365",
		"s:366",
		"s:367",
		"s:368",
		"s:369",
		"s:37",
		"s:370",
		"s:371",
		"s:372",
		"s:373",
		"s:374",
		"s:375",
		"s:376",
		"s:377",
		"s:378",
		"s:379",
		"s:38",
		"s:380",
		"s:381",
		"s:382",
		"s:383",
		"s:384",
		"s:385",
		"s:386",
		"s:387",
		"s:388",
		"s:389",
		"s:39",
		"s:390",
		"s:391",
		"s:392",
		"s:393",
		"s:394",
		"s:395",
		"s:396",
		"s:397",
		"s:398",
		"s:399",
		"s:4",
		"s:40",
		"s:41",
		"s:42",
		"s:43",
		"s:44",
		"s:45",
		"s:46",
		"s:47",
		"s:48",
		"s:49",
		"s:5",
		"s:50",
		"s:51",
		"s:52",
		"s:53",
		"s:54",
		"s:55",
		"s:56",
		"s:57",
		"s:58",
		"s:59",
		"s:6",
		"s:60",
		"s:61",
		"s:62",
		"s:63",
		"s:64",
		"s:65",
		"s:66",
		"s:67",
		"s:68",
		"s:69",
		"s:7",
		"s:70",
		"s:71",
		"s:72",
		"s:73",
		"s:74",
		"s:75",
		"s:76",
		"s:77",
		"s:78",
		"s:79",
		"s:8",
		"s:80",
		"s:81",
		"s:82",
		"s:83",
		"s:84",
		"s:85",
		"s:86",
		"s:87",
		"s:88",
		"s:89",
		"s:9",
		"s:90",
		"s:91",
		"s:92",
		"s:93",
		"s:94",
		"s:95",
		"s:96",
		"s:97",
		"s:98",
		"s:99"};
   /**
	* Servlet initialization method.
	*/
	public void init(ServletConfig config) throws ServletException
	{
		super.init(config);
		java.util.Enumeration en = config.getInitParameterNames();
		while ( en.hasMoreElements() )
		{
			String parm = (String) en.nextElement();
			String value = config.getInitParameter(parm);
			TradeConfig.setConfigParam(parm, value);
		}
		
	}
	
   /**
	* Returns a string that contains information about TradeScenarioServlet
	*
	* @return The servlet information
	*/
	public java.lang.String getServletInfo()
	{
		return "TradeScenarioServlet emulates a population of web users";
	}	



   /**
	* Process incoming HTTP GET requests
	*
	* @param request Object that encapsulates the request to the servlet
	* @param response Object that encapsulates the response from the servlet
	*/
	public void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response)
		throws ServletException, IOException
	{
		//performTask(request,response);
		doRandom(request,response);
	}
	
	

   /**
	* Process incoming HTTP POST requests
	*
	* @param request Object that encapsulates the request to the servlet
	* @param response Object that encapsulates the response from the servlet
	*/
	public void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response)
		throws ServletException, IOException
	{
		//performTask(request,response);
		doRandom(request,response);
	}	

	/* Abhishek : Creating a do Random*/
	public void doRandom(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
		//performScenario
		// singletonoLogger : current timestamp
		// Clear String 
		// Add Db parameter
		long inTime = System.currentTimeMillis();
		int reqcount = SingletonLogger.getInstance().incrementCounter();
		response.setContentType("text/html");
		PrintWriter out = new PrintWriter(response.getOutputStream());
		//out.println("<HTML><HEAD>TradeScenarioServletdoRandom</HEAD><BODY>Hello</BODY></HTML>"); 
		String numberstr =request.getParameter("MAXNUMBER");
		
		long MAXNumber=1000;
		
		if (numberstr!=null){
			try{
			long temp=Integer.parseInt(numberstr);
			//out.println("MAXNUMBER="+temp+"<br>");
			MAXNumber=temp;
			}
			catch(NumberFormatException exp)
			{
				out.println(exp.toString());
			}
		}
		long sum=0;
		for (long i1=1;i1<= MAXNumber;i1++){
			sum=sum+i1;
		}
		
		out.println("<br> Sum="+sum);
		
		long start = System.currentTimeMillis();
		 Random generator = new Random(start);
		 int randomIndex = generator.nextInt(398);
		 
		
		
			
		 String mysymbol=  symbolArray[randomIndex];
		 //out.println("<br>chosen "+mysymbol);
		// System.out.println(this+" Generating Request "+mysymbol);			 		
		 TradeServices tAction = new TradeAction();
		 QuoteDataBean resp;
		try {
			resp = tAction.getQuote(mysymbol);
			out.println(resp.getLow());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//QuoteDataBean resp = ts.getQuote(mysymbol);
		out.close();
		long outTime = System.currentTimeMillis();
		long respTime = outTime - inTime; 
		long dbrespTime = outTime - start; // Added  to get the resp time as time from DB tier.
		//Log.error(" MSU:" + inTime + ":inTime:" +respTime);
		//RAJAT
		StringBuffer Entry= new StringBuffer();
		//Entry.append(respTime);
		int processedcount = SingletonLogger.getInstance().decrementCounter();
		int q_size = SingletonLogger.getInstance().getQueueCounter();
		Entry.append(respTime+":"+q_size+":"+reqcount); //Thesis
		//Entry.append(" MSU:" + inTime + ":inTime:" +respTime+":queue:"+q_size);
		//Entry.append(inTime + ":inTime:" +respTime+":queue:"+q_size); // Modelling
		SingletonLogger.getInstance().insertLog(Entry.toString());
		Log.error(" MSU:" + inTime + ":inTime:" +respTime+":queue:"+q_size+":dbTime:"+dbrespTime); // Changed for DB tier
		//Log.error(" MSU:" + inTime + ":inTime:" +respTime+":queue:"+q_size);
		
	}
	
   /** 
	* Main service method for TradeScenarioServlet
	*
	* @param request Object that encapsulates the request to the servlet
	* @param response Object that encapsulates the response from the servlet
	*/    
	public void performTask(HttpServletRequest req, HttpServletResponse resp)
		throws ServletException, IOException {

		// Scenario generator for Trade2
		char action = ' ';
		String userID = null;

		// String to create full dispatch path to TradeAppServlet w/ request Parameters
		String dispPath = null; // Dispatch Path to TradeAppServlet

		String scenarioAction = (String) req.getParameter("action");
		if ((scenarioAction != null) && (scenarioAction.length() >= 1))
		{
			action = scenarioAction.charAt(0);
			if (action == 'n')
			{ //null;
				try
				{
					resp.setContentType("text/html");
					PrintWriter out = new PrintWriter(resp.getOutputStream());
					out.println("<HTML><HEAD>TradeScenarioServlet</HEAD><BODY>Hello</BODY></HTML>"); 
					out.close();
					return;
	
				}
				catch (Exception e)
				{
					Log.error(
						"trade_client.TradeScenarioServlet.service(...)" + 
						"error creating printwriter from responce.getOutputStream", e);
						
					resp.sendError(
							500, 
						"trade_client.TradeScenarioServlet.service(...): erorr creating and writing to PrintStream created from response.getOutputStream()"); 
				} //end of catch
	
			} //end of action=='n'
		}


		ServletContext ctx = null;
		HttpSession session = null;
		try
		{
			ctx = getServletConfig().getServletContext();
			// These operations require the user to be logged in. Verify the user and if not logged in
			// change the operation to a login
			session = req.getSession(true);
			userID = (String) session.getAttribute("uidBean");
		}
		catch (Exception e)
		{
			Log.error(
				"trade_client.TradeScenarioServlet.service(...): performing " + scenarioAction +
				"error getting ServletContext,HttpSession, or UserID from session" +
				"will make scenarioAction a login and try to recover from there", e);
			userID = null;
			action = 'l';
		}

		if (userID == null)
		{
			action = 'l'; // change to login
			TradeConfig.incrementScenarioCount();
		}
		else if (action == ' ') {
			//action is not specified perform a random operation according to current mix
			// Tell getScenarioAction if we are an original user or a registered user 
			// -- sellDeficits should only be compensated for with original users.
			action = TradeConfig.getScenarioAction(
				userID.startsWith(TradeConfig.newUserPrefix));
		}	
		switch (action)
			{

				case 'q' : //quote 
					dispPath = tasPathPrefix + "quotes&symbols=" + TradeConfig.rndSymbols();
					ctx.getRequestDispatcher(dispPath).include(req, resp);
					break;
				case 'a' : //account
					dispPath = tasPathPrefix + "account";
					ctx.getRequestDispatcher(dispPath).include(req, resp);
					break;
				case 'u' : //update account profile
					dispPath = tasPathPrefix + "account";
					ctx.getRequestDispatcher(dispPath).include(req, resp);

					String fullName = "rnd" + System.currentTimeMillis();
					String address = "rndAddress";
					String   password = "xxx";
					String email = "rndEmail";
					String creditcard = "rndCC";
					dispPath = tasPathPrefix + "update_profile&fullname=" + fullName + 
						"&password=" + password + "&cpassword=" + password + 					
						"&address=" + address +	"&email=" + email + 
						"&creditcard=" +  creditcard;
					ctx.getRequestDispatcher(dispPath).include(req, resp);
					break;
				case 'h' : //home
					dispPath = tasPathPrefix + "home";
					ctx.getRequestDispatcher(dispPath).include(req, resp);
					break;
				case 'l' : //login
					userID = TradeConfig.getUserID();
					String password2 = "xxx";
					dispPath = tasPathPrefix + "login&inScenario=true&uid=" + userID + "&passwd=" + password2;
					ctx.getRequestDispatcher(dispPath).include(req, resp);
						
					// login is successful if the userID is written to the HTTP session
					if (session.getAttribute("uidBean") == null) {
						System.out.println("TradeScenario login failed. Reset DB between runs");
					} 
					break;
				case 'o' : //logout
					dispPath = tasPathPrefix + "logout";
					ctx.getRequestDispatcher(dispPath).include(req, resp);
					break;
				case 'p' : //portfolio
					dispPath = tasPathPrefix + "portfolio";
					ctx.getRequestDispatcher(dispPath).include(req, resp);
					break;
				case 'r' : //register
					//Logout the current user to become a new user
					// see note in TradeServletAction
					req.setAttribute("TSS-RecreateSessionInLogout", Boolean.TRUE);
					dispPath = tasPathPrefix + "logout";
					ctx.getRequestDispatcher(dispPath).include(req, resp);

					userID = TradeConfig.rndNewUserID();
					String passwd = "yyy";
					fullName = TradeConfig.rndFullName();
					creditcard = TradeConfig.rndCreditCard();
					String money = TradeConfig.rndBalance();
					email = TradeConfig.rndEmail(userID);
					String smail = TradeConfig.rndAddress();
					dispPath = tasPathPrefix + "register&Full Name=" + fullName + "&snail mail=" + smail +
						"&email=" + email + "&user id=" + userID + "&passwd=" + passwd + 
						"&confirm passwd=" + passwd + "&money=" + money + 
						"&Credit Card Number=" + creditcard;
					ctx.getRequestDispatcher(dispPath).include(req, resp);
					break;
				case 's' : //sell
					dispPath = tasPathPrefix + "portfolioNoEdge";
					ctx.getRequestDispatcher(dispPath).include(req, resp);
					
					Collection holdings = (Collection) req.getAttribute("holdingDataBeans");
					int numHoldings = holdings.size();
					if (numHoldings > 0)
					{
						//sell first available security out of holding 
						
						Iterator it = holdings.iterator();
						boolean foundHoldingToSell = false;
						while (it.hasNext()) 
						{
							HoldingDataBean holdingData = (HoldingDataBean) it.next();
							if ( !(holdingData.getPurchaseDate().equals(new java.util.Date(0)))  )
							{
								Integer holdingID = holdingData.getHoldingID();

								dispPath = tasPathPrefix + "sell&holdingID="+holdingID;
								ctx.getRequestDispatcher(dispPath).include(req, resp);
								foundHoldingToSell = true;
								break;	
							}
						}
						if (foundHoldingToSell) break;
						if (Log.doTrace())
							Log.trace("TradeScenario: No holding to sell -switch to buy -- userID = " + userID + "  Collection count = " + numHoldings);		

					}
					// At this point: A TradeScenario Sell was requested with No Stocks in Portfolio
					// This can happen when a new registered user happens to request a sell before a buy
					// In this case, fall through and perform a buy instead

					/* Trade 2.037: Added sell_deficit counter to maintain correct buy/sell mix.
					 * When a users portfolio is reduced to 0 holdings, a buy is requested instead of a sell.
					 * This throws off the buy/sell mix by 1. This results in unwanted holding table growth
					 * To fix this we increment a sell deficit counter to maintain the correct ratio in getScenarioAction
					 * The 'z' action from getScenario denotes that this is a sell action that was switched from a buy
					 * to reduce a sellDeficit
					 */
					if (userID.startsWith(TradeConfig.newUserPrefix) == false)
					{
						TradeConfig.incrementSellDeficit();
					}
				case 'b' : //buy
					String symbol = TradeConfig.rndSymbol();
					String amount = TradeConfig.rndQuantity() + "";

					dispPath = tasPathPrefix + "quotes&symbols=" + symbol;
					ctx.getRequestDispatcher(dispPath).include(req, resp);

					dispPath = tasPathPrefix + "buy&quantity=" + amount + "&symbol=" + symbol;
					ctx.getRequestDispatcher(dispPath).include(req, resp);
					break;
			} //end of switch statement 
	}

	// URL Path Prefix for dispatching to TradeAppServlet
	private final static String tasPathPrefix = "/app?action=";

}

